package com.njaccp.dom4j;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;

import java.io.*;
import java.util.Iterator;

public class MyXml {
    public static void main(String[] args) {
        //设置文件路径
        //String filePath="C:\\Users\\Huyang\\IdeaProjects\\MySecond2\\src\\main\\resources\\simple.xml";
        String filePath=System.getProperty("user.dir").concat("\\src\\main\\resources\\simple.xml");
        //解析XML文本
        Document document=MyXml.parseXML(filePath);
        //遍历并打印文本信息
        System.out.println("*************初始状态的DOM4J树*************");
        traverseDOM4J(document);
        System.out.println("*******************************************");

        //向dom树中添加元素
        Element newFood=MyXml.newElement();//方法中创建了一个新元素：food:Chinese Breakfast
        MyXml.addElement(document,newFood);

        //遍历输出添加元素后的DOM4J树
        System.out.println("*************加元素后的DOM4J树*************");
        traverseDOM4J(document);
        System.out.println("*******************************************");

        //保存添加元素后的新DOM4J树到XML文件
        MyXml.saveXML(document,filePath);
    }

    /**
     * 解析XML源文件
     * 通过SAXReader实例的read()方法
     * @param filePath XML源文件路径
     * @return DOM4J树
     */
    public static Document parseXML(String filePath){
        Document parsedDocument=null;
        //创建XML输入对象
        SAXReader saxReader =new SAXReader();
        try {
            //解析XML文件
            parsedDocument=saxReader.read(filePath);
        } catch (DocumentException e) {
            e.printStackTrace();
        }finally {
            return parsedDocument;
        }
    }

    /**
     * 通过根节点遍历DOM4J树
     * @param document
     */
    public static void traverseDOM4J(Document document){
        Element root=document.getRootElement();;//获取文档的根元素结点
        traverseFun(root,0);

    }

    /**
     * 递归遍历
     * @param element 根节点
     * @param deep  当前树的深度
     */
    public static void traverseFun(Element element,int deep){
        for (int i = 0; i < deep; i++) {
            System.out.print("\t");//打印制表符，形成缩进层次
        }
        System.out.print(element.getName());
        if(element.isTextOnly()){
            //如果当前为纯文本则输出文本内容
            System.out.println(":"+element.getText());
        }
        else System.out.println();
        //使用迭代器遍历，遍历当前元素结点所有子元素结点
        Iterator iterator= element.elementIterator();
        while(iterator.hasNext()){
            Element item=(Element)iterator.next();
            traverseFun(item,deep+1);//递归调用
        }
    }

    /**
     * DocumentHelper创建新的元素结点
     * @return
     */
    public static Element newElement(){
        //借助DocumentHelper创建一个新的元素结点
        Element element= DocumentHelper.createElement("food");
        //为元素结点添加子节点
        Element name=element.addElement("name");
        Element price=element.addElement("price");
        Element description=element.addElement("description");
        Element calories=element.addElement("calories");

        //为子节点添加文本内容
        name.addText("Chinese Breakfast");
        price.addText("$5.00");
        description.addText("Soybean milk and fried sticks");
        calories.addText("800");

        return element;
    }

    /**
     * 向DOM4J树中添加一个结点
     * 通过调用文档根元素结点的addElement方法，向根节点中追加新的节点
     * @param document
     * @param newElement 需要添加的结点
     */
    public static void addElement(Document document,Element newElement){
        Element root=document.getRootElement();
        root.add(newElement);
    }

    /**
     * XMLWriter结合OutputFormat输出当前的DOM4J树
     * @param document
     * @param filePath
     */
    public static void saveXML(Document document,String filePath){
        //使用输出格式化工具OutputFormat的createPrettyPrint方法，自动获取格式化的输出（包括缩进）
        OutputFormat outputFormat=OutputFormat.createPrettyPrint();
        //设置输出格式化工具的文本编码
        outputFormat.setEncoding("UTF-8");
        //创建输出工具
        XMLWriter writer=null;
        try {
            //为输出工具给出文件输出流路径和格式
            writer=new XMLWriter(new OutputStreamWriter(new FileOutputStream(filePath)),outputFormat);
            //写出DOM4J树
            writer.write(document);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e){
            e.printStackTrace();
        }finally {
            try {
                //关闭输出流
                writer.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
